package com.taichuan.selfcheck.mvp.presenter;

import android.content.Context;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.util.Pair;
import com.taichuan.mvp.base.MvpBasePresenter;
import com.taichuan.selfcheck.R;
import com.taichuan.selfcheck.config.PathConfig;
import com.taichuan.selfcheck.hardware.audio.MediaRecordClient;
import com.taichuan.selfcheck.hardware.audio.MediaPlayerClient;
import com.taichuan.selfcheck.mvp.viewinterface.TestAudioInterface;

/**
 * Created by CamelLuo on 2018/6/21.
 */
public class TestAudioPresenter extends MvpBasePresenter<TestAudioInterface> {
    private static final String TAG = TestAudioPresenter.class.getSimpleName();

    /**
     * Handler事件类型： 开始执行 自动循环录音测试功能： 小循环录音（执行10秒录音，休息5秒）
     */
    private static final int MSG_AUTO_RECORD_TEST_START_RECORD = 1;

    private static final int MSG_AUTO_RECORD_TEST_STOP_RECORD = 2;

    /**
     * 定义一个变量用于表示 当前自动循环录音测试的执行次数
     */
    private int autoRecordTestDoCount = 1;

    /**
     * 多媒体播放操作类
     */
    private MediaPlayerClient mediaPlayerClient;
    /**
     * 音频管理器
     */
    AudioManager audioManager;
    /**
     * 上下文对象
     */
    private Context context;

    /**
     * 系统铃声
     */
    private Ringtone mRingtone;
    private int startPageStreamMusicVolume;


    public TestAudioPresenter(Context context) {
        this.context = context;
    }

    @Override
    public void attachView(TestAudioInterface view) {
        super.attachView(view);
        mediaPlayerClient = new MediaPlayerClient(context);
        mediaPlayerClient.setMediaPlayerStateCallback((audioResourcesType, audioRawId, audioFilePath) -> {
            if (audioResourcesType == MediaPlayerClient.AUDIO_RESOURCES_TYPE_FILE_PATH){    //播放的是音频文件
                if (audioFilePath.equals(PathConfig.getRecordAudioCacheFilePath())){     //播放的是 单次录音 的缓存录音文件
                    //停止播放录音
                    stopPlayRecord();
                }
            }
        });
    }

    @Override
    public void detachView() {
        super.detachView();
        //销毁资源
        destroy();
    }

    private void destroy(){
        //移除所有Handler事件
        autoTestHandler.removeMessages(MSG_AUTO_RECORD_TEST_START_RECORD);
        autoTestHandler.removeMessages(MSG_AUTO_RECORD_TEST_STOP_RECORD);

        //重置变量
        autoRecordTestDoCount = 1;

        //停止录音并注销资源
        MediaRecordClient.getInstance().stopRecord();
        //注销资源
        MediaRecordClient.getInstance().destroy();

        //停止放音并注销资源
        if (mediaPlayerClient != null){
            mediaPlayerClient.stopAudio();
            mediaPlayerClient.destroy();
        }

        //停止铃声播放
        stopRing();

        //恢复进入该测试页面时的音量大小
        updateMusicVolume(startPageStreamMusicVolume);

        audioManager = null;
    }

    public void initAudioManager(){
        //实例化音频管理器，用于控制音量
        audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        //获取系统当前 的 媒体声音
        startPageStreamMusicVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        //获取系统当前的 最大媒体音量
        int maxStreamMusicVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

        //录音放音测试使用最大音量的80% （11音量）进行
        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,11,0);

        //获取系统铃声
        Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
        mRingtone = RingtoneManager.getRingtone(context, uri);

        //初始化音量调节SeekBar
        getView().initVolumeSeekBar(11,maxStreamMusicVolume);
    }

    /**
     * 定义一个方法用于 开始执行录音
     */
    public void startRecord(boolean isNeedHidePlayTimer){
        //开始录音
        Pair<Boolean, String> resultPair = MediaRecordClient.getInstance().startRecord(PathConfig.getRecordAudioCacheFilePath());
        //通知音量指示计UI 开始根据当前的录音分贝值进行刷新
        getView().refreshVUMeter();
        //通知计时器开始刷新
        getView().startTimerRefreshForRecord(isNeedHidePlayTimer);
        getView().showMsg(resultPair.second);
    }

    /**
     * 定义一个方法用于 停止执行录音
     */
    public void stopRecord(){
        //停止录音
        Pair<Boolean, String> resultPair = MediaRecordClient.getInstance().stopRecord();
        getView().showMsg(resultPair.second);
        //重置Timer计时
        getView().resetTimer();
    }

    /**
     * 定义一个方法用于 开始执行播放录音流程
     */
    public void startPlayRecord(boolean isNeedHideRecordTimer){
        //开始播放录音
        mediaPlayerClient.playAudioByFilePath(PathConfig.getRecordAudioCacheFilePath(),false,
                false, AudioManager.STREAM_MUSIC);
        //通知计时器开始刷新
        getView().startTimerRefreshForPlay(isNeedHideRecordTimer);
    }

    /**
     * 定义一个方法用于 停止执行播放录音流程
     */
    public void stopPlayRecord(){
        //停止播放录音
        mediaPlayerClient.stopAudio();
        //重置Timer计时
        getView().resetTimer();
        //变更按钮UI状态
        getView().openOrClosePlayRecord(true);
    }

    /**
     * 定义一个方法用于 启动 自动循环录音测试
     */
    public void startAutoCycleRecordTest(){
        if (!autoTestHandler.hasMessages(MSG_AUTO_RECORD_TEST_START_RECORD) &&
                !autoTestHandler.hasMessages(MSG_AUTO_RECORD_TEST_STOP_RECORD)) {
            //开始执行自动测试
            autoTestHandler.sendEmptyMessage(MSG_AUTO_RECORD_TEST_START_RECORD);
            Log.e(TAG, "startAutoCycleRecordTest: 开始执行 自动循环录音测试");
        }else {
            getView().showMsg("自动循环录音测试已在执行中，请重新打开测试页面尝试");
        }
    }

    /**
     * 定义一个方法用于 停止 自动循环录音测试
     */
    public void stopAutoCycleRecordTest(){
        //移除所有Handler事件
        autoTestHandler.removeMessages(MSG_AUTO_RECORD_TEST_START_RECORD);
        autoTestHandler.removeMessages(MSG_AUTO_RECORD_TEST_STOP_RECORD);
        //重置变量
        autoRecordTestDoCount = 1;
        //停止录音
        stopRecord();
        //更新UI
        getView().refreshInfoText("");
    }

    /**
     * 定义一个方法用于 开始执行播放 测试音乐流程
     */
    public void startPlayTestMusic(boolean isNeedHideRecordTimer){
        //开始播放录音
        mediaPlayerClient.playAudioByResourcesId(R.raw.test_music_jaychou_summer_day,true,
                true, AudioManager.STREAM_MUSIC);
        //通知计时器开始刷新
        getView().startTimerRefreshForPlay(isNeedHideRecordTimer);
    }

    /**
     * 定义一个方法用于停止 同时录音放音测试
     */
    public void stopRecordAudioWithPlayMusic(){
        //停止录音
        stopRecord();
        //停止播放音乐
        stopPlayTestMusic();
    }

    /**
     * 定义一个方法用于开始 同时录音放音测试
     */
    public void startRecordAudioWithPlayMusic(){
        //开始录音
        startRecord(false);
        //开始播放音乐
        startPlayTestMusic(false);
    }

    /**
     * 定义一个方法用于 停止执行播放录音流程 用于 同时录音放音测试
     */
    public void stopPlayTestMusic(){
        //停止播放录音
        mediaPlayerClient.stopAudio();
        //重置Timer计时
        getView().resetTimer();
    }

    /**
     * 定义一个方法用于更新设备 的媒体音量
     */
    public void updateMusicVolume(int volume){
        if (audioManager != null){
            if (volume >= 0){
                audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,volume,0);
            }
        }else {
            Log.e(TAG, "updateMusicVolume: 音频管理器实例对象为null，无法调节");
        }
    }

    /**
     * 定义一个方法用于播放铃声，用于调节音量时的反馈
     */
    public void playRing() {
//        if (mRingtone != null) {
//            mRingtone.setStreamType(AudioManager.STREAM_MUSIC);
//            mRingtone.play();
//        }
    }

    /**
     * 定义一个方法用于停止播放铃声
     */
    public void stopRing(){
//        if (mRingtone != null) {
//            mRingtone.stop();
//        }
    }


    /**
     * 定义一个Handler 用于实现自动循环录音测试
     */
    private final Handler autoTestHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what){
                case MSG_AUTO_RECORD_TEST_START_RECORD:{
                    if ((autoRecordTestDoCount % 20) != 0) {         //每执行20次高强度短时录音，就执行1次 长冷却录音
                        //开始执行录音
                        startRecordForAutoTest(10);
                    }else {                                         //长冷却录音
                        //开始执行录音
                        startRecordForAutoTest(30);
                    }
                    break;
                }
                case MSG_AUTO_RECORD_TEST_STOP_RECORD:{
                    if ((autoRecordTestDoCount % 20) != 0) {         //每执行20次高强度短时录音，就执行1次 长冷却录音
                        stopRecordForTest(5 * 1000, "停止本次小循环录音，并休眠5秒");
                    }else {                                         //长冷却录音
                        //停止执行录音
                        stopRecordForTest(2 * 60 * 1000, "停止本次大循环录音，并休眠2分钟，请耐心等待");
                    }
                    break;
                }
            }
            return false;
        }

        /**
         * 定义一个方法用于 开始 自动循环录音
         * @param recordTime
         */
        private void startRecordForAutoTest(int recordTime) {
            //开始执行录音
            startRecord(true);
            //执行10秒的录音后停止录音
            autoTestHandler.sendEmptyMessageDelayed(MSG_AUTO_RECORD_TEST_STOP_RECORD, recordTime * 1000);
            String content = "执行第 " + autoRecordTestDoCount + " 次 自动循环录音测试，开始本次循环录音 " + recordTime + " 秒";
            Log.i(TAG, content);
            //更新UI
            getView().refreshInfoText(content);
        }

        /**
         * 定义一个方法用于 停止 自动循环录音，进入休眠期
         * @param sleepTime
         * @param infoMsg
         */
        private void stopRecordForTest(int sleepTime, String infoMsg) {
            //停止执行录音
            stopRecord();
            //休眠5秒后开始下一次录音
            autoTestHandler.sendEmptyMessageDelayed(MSG_AUTO_RECORD_TEST_START_RECORD, sleepTime);
            String content = "执行第 " + autoRecordTestDoCount + " 次 自动循环录音测试，" + infoMsg;
            Log.i(TAG, content);
            //更新UI
            getView().refreshInfoText(content);
            //累计次数+1
            autoRecordTestDoCount++;
        }

    });

    public MediaPlayerClient getMediaPlayerClient() {
        return mediaPlayerClient;
    }
}
